package cn.initcap.controller;

import cn.initcap.common.Result;
import cn.initcap.entity.SeckillUser;
import cn.initcap.redis.GoodsKey;
import cn.initcap.redis.RedisService;
import cn.initcap.service.GoodsService;
import cn.initcap.vo.GoodsDetailVo;
import cn.initcap.vo.GoodsVo;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;

/**
 * @author initcap
 * @date Created in 2018/8/10 PM3:59.
 */
@Controller
@RequestMapping("/goods")
public class GoodsController extends BaseController {

    private ThymeleafViewResolver thymeleafViewResolver;
    private RedisService redisService;
    private GoodsService goodsService;
    private ApplicationContext applicationContext;

    @Autowired
    public GoodsController(ThymeleafViewResolver thymeleafViewResolver, RedisService redisService,
                           GoodsService goodsService, ApplicationContext applicationContext) {
        super(thymeleafViewResolver, redisService);
        this.thymeleafViewResolver = thymeleafViewResolver;
        this.redisService = redisService;
        this.goodsService = goodsService;
        this.applicationContext = applicationContext;
    }

    /**
     * QPS:1267 load:15 mysql
     * 5000 * 10
     * QPS:2884, load:5
     */
    @RequestMapping(value = "/to_list")
    public String list(HttpServletRequest request, HttpServletResponse response, Model model, SeckillUser user) {
        model.addAttribute("user", user);
        List<GoodsVo> goodsList = goodsService.listGoodsVo();
        model.addAttribute("goodsList", goodsList);
        return render(request, response, model, "goods_list", GoodsKey.GET_GOODS_LIST, "");
    }

    @RequestMapping(value = "/to_detail2/{goodsId}", produces = "text/html")
    @ResponseBody
    public String detail2(HttpServletRequest request, HttpServletResponse response, Model model, SeckillUser user,
                          @PathVariable("goodsId") long goodsId) {
        model.addAttribute("user", user);

        //取缓存
        String html = redisService.get(GoodsKey.GET_GOODS_DETAIL, "" + goodsId, String.class);
        if (!StringUtils.isEmpty(html)) {
            return html;
        }
        //手动渲染
        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
        model.addAttribute("goods", goods);

        // 设置秒杀状态与时间
        GetStatusAndSecond getStatusAndSecond = new GetStatusAndSecond(goods).invoke();
        model.addAttribute("miaoshaStatus", getStatusAndSecond.getMiaoshaStatus());
        model.addAttribute("remainSeconds", getStatusAndSecond.getRemainSeconds());

        WebContext ctx = new WebContext(request, response, request.getServletContext(), request.getLocale(), model.asMap());
        html = thymeleafViewResolver.getTemplateEngine().process("goods_detail", ctx);
        if (!StringUtils.isEmpty(html)) {
            redisService.set(GoodsKey.GET_GOODS_DETAIL, "" + goodsId, html);
        }
        return html;
    }

    @RequestMapping(value = "/detail/{goodsId}")
    @ResponseBody
    public Result detail(SeckillUser user,
                         @PathVariable("goodsId") long goodsId) {
        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);

        // 设置秒杀状态与时间
        GetStatusAndSecond getStatusAndSecond = new GetStatusAndSecond(goods).invoke();

        GoodsDetailVo vo = new GoodsDetailVo();
        vo.setGoods(goods);
        vo.setUser(user);
        vo.setRemainSeconds(getStatusAndSecond.getRemainSeconds());
        vo.setMiaoshaStatus(getStatusAndSecond.getMiaoshaStatus());
        return Result.success(vo);
    }

    private class GetStatusAndSecond {
        private GoodsVo goods;
        private int miaoshaStatus;
        private int remainSeconds;

        private GetStatusAndSecond(GoodsVo goods) {
            this.goods = goods;
        }

        private int getMiaoshaStatus() {
            return miaoshaStatus;
        }

        private int getRemainSeconds() {
            return remainSeconds;
        }

        private GetStatusAndSecond invoke() {
            long startAt = goods.getStartDate().getTime();
            long endAt = goods.getEndDate().getTime();
            long now = System.currentTimeMillis();
            //秒杀还没开始，倒计时
            if (now < startAt) {
                miaoshaStatus = 0;
                remainSeconds = (int) ((startAt - now) / 1000);
                //秒杀已经结束
            } else if (now > endAt) {
                miaoshaStatus = 2;
                remainSeconds = -1;
                //秒杀进行中
            } else {
                miaoshaStatus = 1;
                remainSeconds = 0;
            }
            return this;
        }
    }
}
